package com.gitee.huanminabc.jcommon.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class ClassUtil {

    //这种方式加载类,不会导致类进行初始化 比如static代码块  , 只有实际使用部分方法了比如xxx.getName()才会执行
    //而Class.forName()会立马进行类初始化, 会执行static代码块
    public static Class<?> loadClass(String className) throws ClassNotFoundException {
        return Thread.currentThread().getContextClassLoader().loadClass(className);
    }
    //判断类的构造函数是否大于1
    public static boolean hasMoreThanOneConstructor(Class<?> clazz) {
        try {
            Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
            return declaredConstructors.length > 1;
        } catch (Exception e) {
            throw new RuntimeException("Failed to check constructors of class: " + clazz.getName(), e);
        }
    }
    //根据Class创建对象 优先最大构造如果不行就无参还不行就报错
    public static <T> T newInstance(Class<T> clazz) {
        try {
            //获取是否存在构造函数
            //如果没有构造函数,则使用默认的构造函数
            //如果有构造函数,则使用最多参数的构造函数, 参数默认是,默认值,如果是对象类型,则使用null
            Constructor<?> maxConstructor = getMaxConstructor(clazz);
            //获取构造函数的参数类型
            Class<?>[] parameterTypes = maxConstructor.getParameterTypes();
            //获取构造函数的参数值
            Object[] args = new Object[parameterTypes.length];
            for (int i = 0; i < parameterTypes.length; i++) {
                //获取参数类型
                Class<?> parameterType = parameterTypes[i];
                //获取参数值
                args[i] = getDefaultValue(parameterType);
            }
            //创建对象
            maxConstructor.setAccessible(true);
            return (T) maxConstructor.newInstance(args);
        } catch (Exception e) {
            //如果失败尝试使用无参的构造函数
            try {
                Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
                //找到没有参数的构造函数
                for (Constructor<?> declaredConstructor : declaredConstructors) {
                    if (declaredConstructor.getParameterCount() == 0) {
                        //如果是private,则设置为可访问
                        if (Modifier.isPrivate(declaredConstructor.getModifiers())) {
                            declaredConstructor.setAccessible(true);
                        }
                        return (T) declaredConstructor.newInstance();
                    }
                }
            } catch (Exception e1) {
                return null;
            }
            return null;
        }
    }

    //获取类最大参数的构造函数
    public static Constructor<?> getMaxConstructor(Class<?> clazz) {
        try {
            //获取是否存在构造函数
            //如果没有构造函数,则使用默认的构造函数
            //如果有构造函数,则使用最多参数的构造函数, 参数默认是,默认值,如果是对象类型,则使用null
            Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
            if (declaredConstructors.length == 0) {
                return clazz.getDeclaredConstructor();
            }
            Constructor<?> maxConstructor = declaredConstructors[0];
            for (Constructor<?> constructor : declaredConstructors) {
                if (constructor.getParameterCount() > maxConstructor.getParameterCount()) {
                    maxConstructor = constructor;
                }
            }
            return maxConstructor;
        } catch (Exception e) {
            throw new RuntimeException("Failed to get max constructor of class: " + clazz.getName(), e);
        }
    }
    //获取默认值
    private static Object getDefaultValue(Class<?> clazz) {
        if (clazz.isPrimitive()) {
            if (clazz == boolean.class) {
                return false;
            } else if (clazz == byte.class) {
                return (byte) 0;
            } else if (clazz == char.class) {
                return '\u0000';
            } else if (clazz == short.class) {
                return (short) 0;
            } else if (clazz == int.class) {
                return 0;
            } else if (clazz == long.class) {
                return 0L;
            } else if (clazz == float.class) {
                return 0.0f;
            } else if (clazz == double.class) {
                return 0.0d;
            }
        }
        return null; // 对于非基本类型，返回null
    }

    //这个只能找类上继承的接口包括父类, 但是不能找接口内部继承的接口
    public static Class<?>[] getAllInterfaces(Class<?> cls) {
        Set<Class<?>> interfaces = new HashSet<>();
        while (cls != null) {
            Class<?>[] ifs = cls.getInterfaces();
            interfaces.addAll(Arrays.asList(ifs));
            cls = cls.getSuperclass();//继承的父类
        }
        return interfaces.toArray(new Class<?>[0]);
    }
    //这个只能找类上继承的接口包括父类, 包括接口内部继承的接口
    public static Class<?>[] getAllSuperInterfaces(Class<?> cls) {
        Set<Class<?>> interfaces = new HashSet<>();
        while (cls != null) {
            Class<?>[] ifs = cls.getInterfaces();
            interfaces.addAll(Arrays.asList(ifs));
            for (Class<?> anInterface : ifs) {
                interfaces.addAll(Arrays.asList(getAllSuperInterfaces(anInterface)));
            }
            cls = cls.getSuperclass();//继承的父类
        }
        return interfaces.toArray(new Class<?>[0]);

    }
}
